{ "cells": [ { "cell_type": "markdown", "metadata": { "school_cell_uuid": "3fd41a030d7c44f69578ad1b99db7437" }, "source": [ "# 4.4 데이터프레임의 데이터 조작" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "0963b108717745d2b82b4941ae59cd67" }, "source": [ "판다스는 넘파이 2차원 배열에서 가능한 대부분의 데이터 처리가 가능하며 추가로 데이터 처리 및 변환을 위한 다양한 함수와 메서드를 제공한다." ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "54394646eb4e488c84bb91908bc326d0" }, "source": [ "## 데이터 갯수 세기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "`count`\n", "```" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "ec160e26453644cb9896704dadfb0b5c" }, "source": [ "가장 간단한 데이터 분석은 데이터의 갯수를 세는 것이다. `count` 메서드를 사용한다. NaN 값은 세지 않는다." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "school_cell_uuid": "87f90076786847f49036d99249e4ee6a" }, "outputs": [ { "data": { "text/plain": [ "0 0.0\n", "1 1.0\n", "2 2.0\n", "3 NaN\n", "4 4.0\n", "5 5.0\n", "6 6.0\n", "7 7.0\n", "8 8.0\n", "9 9.0\n", "dtype: float64" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = pd.Series(range(10))\n", "s[3] = np.nan\n", "s" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "school_cell_uuid": "689ceffec1134035b8ab1bb31822eb72" }, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.count()" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "66076050617144f09682db0dfed06b0e" }, "source": [ "데이터프레임에서는 각 열마다 별도로 데이터 갯수를 센다. 데이터에서 값이 누락된 부분을 찾을 때 유용하다." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "school_cell_uuid": "1c05d676360a4f66935610e846562ddb" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
00.00.03.02.0
13.00.02.01.0
23.02.04.0NaN
34.03.04.02.0
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 0.0 0.0 3.0 2.0\n", "1 3.0 0.0 2.0 1.0\n", "2 3.0 2.0 4.0 NaN\n", "3 4.0 3.0 4.0 2.0" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.seed(2)\n", "df = pd.DataFrame(np.random.randint(5, size=(4, 4)), dtype=float)\n", "df.iloc[2, 3] = np.nan\n", "df" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "school_cell_uuid": "6a29547057514467817bb4832f7deb26" }, "outputs": [ { "data": { "text/plain": [ "0 4\n", "1 4\n", "2 4\n", "3 3\n", "dtype: int64" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.count()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "다음 명령으로 타이타닉호의 승객 데이터를 데이터프레임으로 읽어올 수 있다. 이 명령을 실행하려면 seaborn 패키지가 설치되어 있어야 한다." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealone
003male22.0107.2500SThirdmanTrueNaNSouthamptonnoFalse
111female38.01071.2833CFirstwomanFalseCCherbourgyesFalse
213female26.0007.9250SThirdwomanFalseNaNSouthamptonyesTrue
311female35.01053.1000SFirstwomanFalseCSouthamptonyesFalse
403male35.0008.0500SThirdmanTrueNaNSouthamptonnoTrue
\n", "
" ], "text/plain": [ " survived pclass sex age sibsp parch fare embarked class \\\n", "0 0 3 male 22.0 1 0 7.2500 S Third \n", "1 1 1 female 38.0 1 0 71.2833 C First \n", "2 1 3 female 26.0 0 0 7.9250 S Third \n", "3 1 1 female 35.0 1 0 53.1000 S First \n", "4 0 3 male 35.0 0 0 8.0500 S Third \n", "\n", " who adult_male deck embark_town alive alone \n", "0 man True NaN Southampton no False \n", "1 woman False C Cherbourg yes False \n", "2 woman False NaN Southampton yes True \n", "3 woman False C Southampton yes False \n", "4 man True NaN Southampton no True " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import seaborn as sns\n", "titanic = sns.load_dataset(\"titanic\")\n", "titanic.head()" ] }, { "cell_type": "markdown", "metadata": { "bootstrap": { "panel": { "class": "panel-default" } }, "school_cell_uuid": "52ea3c810b334e7b96bd3671d227f7d1" }, "source": [ "````{admonition} 연습 문제 4.4.1\n", "\n", "타이타닉호 승객 데이터의 데이터 개수를 각 열마다 구해본다.\n", "````" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "6bb4a473517e48a0a4c571c1150b08a5" }, "source": [ "## 카테고리 값 세기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "`value_counts`\n", "```" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "5aa39de8b9a846e1833d970b92b6fcfc" }, "source": [ "시리즈의 값이 정수, 문자열, 카테고리 값인 경우에는 `value_counts` 메서드로 각각의 값이 나온 횟수를 셀 수 있다." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "school_cell_uuid": "992cb9b1a3634783a9f3a5e96a6834db" }, "outputs": [ { "data": { "text/plain": [ "95 4\n", "96 5\n", "97 2\n", "98 4\n", "99 3\n", "dtype: int64" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.seed(1)\n", "s2 = pd.Series(np.random.randint(6, size=100))\n", "s2.tail()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1 22\n", "0 18\n", "4 17\n", "5 16\n", "3 14\n", "2 13\n", "dtype: int64" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2.value_counts()" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "e023197594ea4fbdbef80d7a898206f3" }, "source": [ "데이터프레임에는 `value_counts` 메서드가 없으므로 각 열마다 별도로 적용해야 한다." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "school_cell_uuid": "a8b131c3cb914b9ba0178e4e2c09bc11" }, "outputs": [ { "data": { "text/plain": [ "3.0 2\n", "4.0 1\n", "0.0 1\n", "Name: 0, dtype: int64" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[0].value_counts()" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "62e666d9e8104d16bdcbd30d1f6df65f" }, "source": [ "## 정렬" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "`sort_index`\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "`sort_values`\n", "```" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "894cc2cf62ab4a06b64f2786b131b5e2" }, "source": [ "데이터를 정렬하려면 `sort_index` 메서드 `sort_values` 메서드를 사용한다. `sort_index` 메서드는 인덱스 값을 기준으로, `sort_values` 메서드는 데이터 값을 기준으로 정렬한다.\n", "\n", "앞에서 `s2` 시리즈의 각 데이터 값에 따른 데이터 갯수를 인덱스에 따라 정렬하려면 다음처럼 `sort_index`를 적용한다." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "school_cell_uuid": "edb6d322399e48cdad010d3aec63ca6c" }, "outputs": [ { "data": { "text/plain": [ "0 18\n", "1 22\n", "2 13\n", "3 14\n", "4 17\n", "5 16\n", "dtype: int64" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s2.value_counts().sort_index()" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "27db8202e06e4e87825585643e000158" }, "source": [ "NaN값이 있는 경우에는 정렬하면 NaN값이 가장 나중으로 간다." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "school_cell_uuid": "fb8f40c9e82e48a1a396eb38831811f7" }, "outputs": [ { "data": { "text/plain": [ "0 0.0\n", "1 1.0\n", "2 2.0\n", "4 4.0\n", "5 5.0\n", "6 6.0\n", "7 7.0\n", "8 8.0\n", "9 9.0\n", "3 NaN\n", "dtype: float64" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.sort_values()" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "7c6a42bbed964948966250321edcc690" }, "source": [ "큰 수에서 작은 수로 반대 방향 정렬하려면 `ascending=False` 인수를 지정한다." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "school_cell_uuid": "1b5d13aaa77a4b918198bb73275a761d" }, "outputs": [ { "data": { "text/plain": [ "9 9.0\n", "8 8.0\n", "7 7.0\n", "6 6.0\n", "5 5.0\n", "4 4.0\n", "2 2.0\n", "1 1.0\n", "0 0.0\n", "3 NaN\n", "dtype: float64" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.sort_values(ascending=False)" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "8755625d893b4e3a84eca152c06068e0" }, "source": [ "데이터프레임에서 `sort_values` 메서드를 사용하려면 `by` 인수로 정렬 기준이 되는 열을 지정해 주어야 한다." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "school_cell_uuid": "8cb3762a4ac348d198d2a82d39d99a15" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
00.00.03.02.0
13.00.02.01.0
23.02.04.0NaN
34.03.04.02.0
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 0.0 0.0 3.0 2.0\n", "1 3.0 0.0 2.0 1.0\n", "2 3.0 2.0 4.0 NaN\n", "3 4.0 3.0 4.0 2.0" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(by=1)" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "40ef414a10914866b2cc93ead109d1c4" }, "source": [ "`by` 인수에 리스트 값을 넣으면 이 순서대로 정렬 기준의 우선 순위가 된다. 즉, 리스트의 첫번째 열을 기준으로 정렬한 후 동일한 값이 나오면 그 다음 열로 순서를 따지게 된다." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "school_cell_uuid": "579b0ea2b01043969dd660c78f3cbac2" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
13.00.02.01.0
00.00.03.02.0
23.02.04.0NaN
34.03.04.02.0
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "1 3.0 0.0 2.0 1.0\n", "0 0.0 0.0 3.0 2.0\n", "2 3.0 2.0 4.0 NaN\n", "3 4.0 3.0 4.0 2.0" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(by=[1, 2])" ] }, { "cell_type": "markdown", "metadata": { "bootstrap": { "panel": { "class": "panel-default" } }, "school_cell_uuid": "03c5751991a94aae92991778996db5ed" }, "source": [ "````{admonition} 연습 문제 4.4.2\n", "\n", "`sort_values` 메서드를 사용하여 타이타닉호 승객에 대해 성별(sex) 인원수, 나이별(age) 인원수, 선실별(class) 인원수, 사망/생존(alive) 인원수를 구하라.\n", "````" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "7a266cc6d4c04ef2ad47f789d0175bea" }, "source": [ "## 행/열 합계" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "`sum`\n", "```" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "a9b1d2ca7d6e458eb1ae30445393345a" }, "source": [ "행과 열의 합계를 구할 때는 `sum(axis)` 메서드를 사용한다. `axis` 인수에는 합계로 인해 없어지는 방향축(0=행, 1=열)을 지정한다." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "school_cell_uuid": "586a6c235051415c8810413b6bbfd159" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01234567
058950017
169245242
247791706
399769101
\n", "
" ], "text/plain": [ " 0 1 2 3 4 5 6 7\n", "0 5 8 9 5 0 0 1 7\n", "1 6 9 2 4 5 2 4 2\n", "2 4 7 7 9 1 7 0 6\n", "3 9 9 7 6 9 1 0 1" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.seed(1)\n", "df2 = pd.DataFrame(np.random.randint(10, size=(4, 8)))\n", "df2" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "6373e125af3746d1baa8d91402cebfa5" }, "source": [ "행방향 합계를 구할 때는 `sum(axis=1)` 메서드를 사용한다." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "school_cell_uuid": "9844dea5844a446fa17bdac5b55696dd" }, "outputs": [ { "data": { "text/plain": [ "0 35\n", "1 34\n", "2 41\n", "3 42\n", "dtype: int64" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2.sum(axis=1)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "school_cell_uuid": "8c85292240444dc3b4958c088bbb04f2" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01234567RowSum
05895001735
16924524234
24779170641
39976910142
\n", "
" ], "text/plain": [ " 0 1 2 3 4 5 6 7 RowSum\n", "0 5 8 9 5 0 0 1 7 35\n", "1 6 9 2 4 5 2 4 2 34\n", "2 4 7 7 9 1 7 0 6 41\n", "3 9 9 7 6 9 1 0 1 42" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2[\"RowSum\"] = df2.sum(axis=1)\n", "df2" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "42215ee49dee4709a7b4a1b626ca56e1" }, "source": [ "열 합계를 구할 때는 `sum(axis=0)` 메서드를 사용하는데 `axis`인수의 디폴트 값이 0이므로 `axis`인수를 생략할 수 있다." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "school_cell_uuid": "47a21f35652b4a6dba4f225bca292aaf" }, "outputs": [ { "data": { "text/plain": [ "0 24\n", "1 33\n", "2 25\n", "3 24\n", "4 15\n", "5 10\n", "6 5\n", "7 16\n", "RowSum 152\n", "dtype: int64" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2.sum()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "school_cell_uuid": "366ff3b3379142f09f85ea7055151f5b" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01234567RowSum
05.08.09.05.00.00.01.07.035.0
16.09.02.04.05.02.04.02.034.0
24.07.07.09.01.07.00.06.041.0
39.09.07.06.09.01.00.01.042.0
ColTotal24.033.025.024.015.010.05.016.0152.0
\n", "
" ], "text/plain": [ " 0 1 2 3 4 5 6 7 RowSum\n", "0 5.0 8.0 9.0 5.0 0.0 0.0 1.0 7.0 35.0\n", "1 6.0 9.0 2.0 4.0 5.0 2.0 4.0 2.0 34.0\n", "2 4.0 7.0 7.0 9.0 1.0 7.0 0.0 6.0 41.0\n", "3 9.0 9.0 7.0 6.0 9.0 1.0 0.0 1.0 42.0\n", "ColTotal 24.0 33.0 25.0 24.0 15.0 10.0 5.0 16.0 152.0" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2.loc[\"ColTotal\", :] = df2.sum()\n", "df2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "`mean`\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`mean` 메서드는 평균을 구하며 `sum` 메서드와 사용법이 같다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "````{admonition} 연습 문제 4.4.3\n", "\n", "1. 타이타닉호 승객의 평균 나이를 구하라.\n", "1. 타이타닉호 승객중 여성 승객의 평균 나이를 구하라.\n", "1. 타이타닉호 승객중 1등실 선실의 여성 승객의 평균 나이를 구하라.\n", "````" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "486c0b5123f74b02b7ca909ddc6c5653" }, "source": [ "## `apply` 변환\n", "\n", "행이나 열 단위로 더 복잡한 처리를 하고 싶을 때는 `apply` 메서드를 사용한다. 인수로 행 또는 열을 받는 함수를 `apply` 메서드의 인수로 넣으면 각 열(또는 행)을 반복하여 그 함수에 적용시킨다. " ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "school_cell_uuid": "4702f3d64a7d4f259fc6def7714f0dc9" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABC
0121
1335
2412
3324
4434
\n", "
" ], "text/plain": [ " A B C\n", "0 1 2 1\n", "1 3 3 5\n", "2 4 1 2\n", "3 3 2 4\n", "4 4 3 4" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df3 = pd.DataFrame({\n", " 'A': [1, 3, 4, 3, 4],\n", " 'B': [2, 3, 1, 2, 3],\n", " 'C': [1, 5, 2, 4, 4]\n", "})\n", "df3" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "6576e09a390443b88003bfb3bd4341db" }, "source": [ "예를 들어 각 열의 최대값과 최소값의 차이를 구하고 싶으면 다음과 같은 람다 함수를 넣는다." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "school_cell_uuid": "03ece47f9c944d75890a488dacf7a342" }, "outputs": [ { "data": { "text/plain": [ "A 3\n", "B 2\n", "C 4\n", "dtype: int64" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df3.apply(lambda x: x.max() - x.min())" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "48ce18777f7d4e63a4845eff6f5964fc" }, "source": [ "만약 행에 대해 적용하고 싶으면 `axis=1` 인수를 쓴다." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "school_cell_uuid": "888a82bf2ae84aa58d7e0653ddd482a7" }, "outputs": [ { "data": { "text/plain": [ "0 1\n", "1 2\n", "2 3\n", "3 2\n", "4 1\n", "dtype: int64" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df3.apply(lambda x: x.max() - x.min(), axis=1)" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "aef8dca1c38b458183e7fcd51dc3885c" }, "source": [ "각 열에 대해 어떤 값이 얼마나 사용되었는지 알고 싶다면 `value_counts` 함수를 넣으면 된다." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "school_cell_uuid": "f75cf5ec3249468ba1d59a6fa7c7dfaa" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABC
11.01.01.0
2NaN2.01.0
32.02.0NaN
42.0NaN2.0
5NaNNaN1.0
\n", "
" ], "text/plain": [ " A B C\n", "1 1.0 1.0 1.0\n", "2 NaN 2.0 1.0\n", "3 2.0 2.0 NaN\n", "4 2.0 NaN 2.0\n", "5 NaN NaN 1.0" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df3.apply(pd.value_counts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "다음과 같이 타이타닉호의 승객 중 나이 20살을 기준으로 성인(adult)과 미성년자(child)를 구별하는 라벨 열을 만들 수 있다." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
survivedpclasssexagesibspparchfareembarkedclasswhoadult_maledeckembark_townalivealoneadult/child
88602male27.00013.00SSecondmanTrueNaNSouthamptonnoTrueadult
88711female19.00030.00SFirstwomanFalseBSouthamptonyesTruechild
88803femaleNaN1223.45SThirdwomanFalseNaNSouthamptonnoFalsechild
88911male26.00030.00CFirstmanTrueCCherbourgyesTrueadult
89003male32.0007.75QThirdmanTrueNaNQueenstownnoTrueadult
\n", "
" ], "text/plain": [ " survived pclass sex age sibsp parch fare embarked class \\\n", "886 0 2 male 27.0 0 0 13.00 S Second \n", "887 1 1 female 19.0 0 0 30.00 S First \n", "888 0 3 female NaN 1 2 23.45 S Third \n", "889 1 1 male 26.0 0 0 30.00 C First \n", "890 0 3 male 32.0 0 0 7.75 Q Third \n", "\n", " who adult_male deck embark_town alive alone adult/child \n", "886 man True NaN Southampton no True adult \n", "887 woman False B Southampton yes True child \n", "888 woman False NaN Southampton no False child \n", "889 man True C Cherbourg yes True adult \n", "890 man True NaN Queenstown no True adult " ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "titanic[\"adult/child\"] = titanic.apply(lambda r: \"adult\" if r.age >= 20 else \"child\", axis=1)\n", "titanic.tail()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "````{admonition} 연습 문제 4.4.4\n", "\n", "타이타닉호의 승객에 대해 나이와 성별에 의한 카테고리 열인 `category1` 열을 만들어라. `category1` 카테고리는 다음과 같이 정의된다.\n", "\n", "1. 20살이 넘으면 성별을 그대로 사용한다.\n", "2. 20살 미만이면 성별에 관계없이 \"child\"라고 한다.\n", "\n", "````" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `fillna` 메서드" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "90019eeec686415286bd4da74527c3ce" }, "source": [ "NaN 값은 `fillna` 메서드를 사용하여 원하는 값으로 바꿀 수 있다." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "school_cell_uuid": "1b2fea7973bb4359b350583d8be07024" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABC
11.01.01.0
20.02.01.0
32.02.00.0
42.00.02.0
50.00.01.0
\n", "
" ], "text/plain": [ " A B C\n", "1 1.0 1.0 1.0\n", "2 0.0 2.0 1.0\n", "3 2.0 2.0 0.0\n", "4 2.0 0.0 2.0\n", "5 0.0 0.0 1.0" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df3.apply(pd.value_counts).fillna(0.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "````{admonition} 연습 문제 4.4.5\n", "\n", "타이타닉호의 승객 중 나이를 명시하지 않은 고객은 나이를 명시한 고객의 평균 나이 값이 되도록 titanic 데이터프레임을 고쳐라.\n", "\n", "````" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `astype` 메서드" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`astype` 메서드로 전체 데이터의 자료형을 바꾸는 것도 가능하다." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "school_cell_uuid": "1b2fea7973bb4359b350583d8be07024" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ABC
1111
2021
3220
4202
5001
\n", "
" ], "text/plain": [ " A B C\n", "1 1 1 1\n", "2 0 2 1\n", "3 2 2 0\n", "4 2 0 2\n", "5 0 0 1" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df3.apply(pd.value_counts).fillna(0).astype(int)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "````{admonition} 연습 문제 4.4.6\n", "\n", "타이타닉호의 승객에 대해 나이와 성별에 의한 카테고리 열인 `category2` 열을 만들어라. `category2` 카테고리는 다음과 같이 정의된다.\n", "\n", "1. 성별을 나타내는 문자열 `male` 또는 `female`로 시작한다.\n", "2. 성별을 나타내는 문자열 뒤에 나이를 나타내는 문자열이 온다.\n", "3. 예를 들어 27살 남성은 `male27` 값이 된다.\n", "\n", "````" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "577d980581ce450c93dd3e89b7fdaf26" }, "source": [ "## 실수 값을 카테고리 값으로 변환" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "4d619cf8f65a4b5e83eb0f37bdf116cf" }, "source": [ "실수 값을 크기 기준으로 하여 카테고리 값으로 변환하고 싶을 때는 다음과 같은 명령을 사용한다.\n", "\n", "* `cut`: 실수 값의 경계선을 지정하는 경우\n", "* `qcut`: 갯수가 똑같은 구간으로 나누는 경우" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "542343aa2e4a4a089a12631a5b90884a" }, "source": [ "예를 들어 다음과 같은 나이 데이터가 있다고 하자." ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "school_cell_uuid": "99df3602984b4d6b887eefd783f659b8" }, "outputs": [], "source": [ "ages = [0, 2, 10, 21, 23, 37, 31, 61, 20, 41, 32, 101]" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "f4effa6983944a0da9299a2e921f2af4" }, "source": [ "`cut` 명령을 사용하면 실수값을 다음처럼 카테고리 값으로 바꿀 수 있다. `bins` 인수는 카테고리를 나누는 기준값이 된다. 영역을 넘는 값은 NaN으로 처리된다." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "school_cell_uuid": "c40da6498b75442e8c383aaeeef59ef4" }, "outputs": [ { "data": { "text/plain": [ "[NaN, 미성년자, 미성년자, 청년, 청년, ..., 장년, 미성년자, 중년, 중년, NaN]\n", "Length: 12\n", "Categories (5, object): [미성년자 < 청년 < 중년 < 장년 < 노년]" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bins = [1, 20, 30, 50, 70, 100]\n", "labels = [\"미성년자\", \"청년\", \"중년\", \"장년\", \"노년\"]\n", "cats = pd.cut(ages, bins, labels=labels)\n", "cats" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "c1968d5fb26c49dd96caae34f1a6ee81" }, "source": [ "`cut` 명령이 반환하는 값은 `Categorical` 클래스 객체이다. 이 객체는 `categories` 속성으로 라벨 문자열을, `codes` 속성으로 정수로 인코딩한 카테고리 값을 가진다." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "school_cell_uuid": "dc3697983615455583e6e98d36ae70e3" }, "outputs": [ { "data": { "text/plain": [ "pandas.core.arrays.categorical.Categorical" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(cats)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "school_cell_uuid": "7f79041f92664a158ef5912bbdf939e6" }, "outputs": [ { "data": { "text/plain": [ "Index(['미성년자', '청년', '중년', '장년', '노년'], dtype='object')" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cats.categories" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "school_cell_uuid": "3864753d5bce42ae8cde949ada360e3b" }, "outputs": [ { "data": { "text/plain": [ "array([-1, 0, 0, 1, 1, 2, 2, 3, 0, 2, 2, -1], dtype=int8)" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cats.codes" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "school_cell_uuid": "f12a4b9cff6d4c32b69ff869af092c59" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
agesage_cat
00NaN
12미성년자
210미성년자
321청년
423청년
537중년
631중년
761장년
820미성년자
941중년
1032중년
11101NaN
\n", "
" ], "text/plain": [ " ages age_cat\n", "0 0 NaN\n", "1 2 미성년자\n", "2 10 미성년자\n", "3 21 청년\n", "4 23 청년\n", "5 37 중년\n", "6 31 중년\n", "7 61 장년\n", "8 20 미성년자\n", "9 41 중년\n", "10 32 중년\n", "11 101 NaN" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df4 = pd.DataFrame(ages, columns=[\"ages\"])\n", "df4[\"age_cat\"] = pd.cut(df4.ages, bins, labels=labels)\n", "df4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "따라서 위 데이터프레임의 age_cat 열값은 문자열이 아니다. 이를 문자열로 만들려면 `astype` 메서드를 사용해야 한다." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 nan0\n", "1 미성년자2\n", "2 미성년자10\n", "3 청년21\n", "4 청년23\n", "5 중년37\n", "6 중년31\n", "7 장년61\n", "8 미성년자20\n", "9 중년41\n", "10 중년32\n", "11 nan101\n", "dtype: object" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df4.age_cat.astype(str) + df4.ages.astype(str)" ] }, { "cell_type": "markdown", "metadata": { "school_cell_uuid": "b9b478ddb13643988ddc5ba0ca89dfae" }, "source": [ "`qcut` 명령은 구간 경계선을 지정하지 않고 데이터 갯수가 같도록 지정한 수의 구간으로 나눈다. 예를 들어 다음 코드는 1000개의 데이터를 4개의 구간으로 나누는데 각 구간은 250개씩의 데이터를 가진다." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "school_cell_uuid": "e7d988c3a6a048eb93552b21042a4b69" }, "outputs": [ { "data": { "text/plain": [ "[Q2, Q1, Q2, Q3, Q1, ..., Q1, Q1, Q4, Q4, Q2]\n", "Length: 1000\n", "Categories (4, object): [Q1 < Q2 < Q3 < Q4]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = np.random.randn(1000)\n", "cats = pd.qcut(data, 4, labels=[\"Q1\", \"Q2\", \"Q3\", \"Q4\"])\n", "cats" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "school_cell_uuid": "3bb43c9788744d728a8d874986fa60d9" }, "outputs": [ { "data": { "text/plain": [ "Q4 250\n", "Q3 250\n", "Q2 250\n", "Q1 250\n", "dtype: int64" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.value_counts(cats)" ] }, { "cell_type": "markdown", "metadata": { "bootstrap": { "panel": { "class": "panel-default" } }, "school_cell_uuid": "8493e72b7359403ebc0d8c3df945d6bf" }, "source": [ "````{admonition} 연습 문제 4.4.7\n", "\n", "타이타닉호 승객을 '미성년자', '청년', '중년', '장년', '노년' 나이 그룹으로 나눈다.\n", "\n", "```\n", "bins = [1, 20, 30, 50, 70, 100]\n", "labels = [\"미성년자\", \"청년\", \"중년\", \"장년\", \"노년\"]\n", "```\n", "\n", "그리고 각 나이 그룹의 승객 비율을 구한다. 비율의 전체 합은 1이 되어야 한다.\n", "````" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "````{admonition} 연습 문제 4.4.8\n", "\n", "타이타닉호의 승객에 대해 나이와 성별에 의한 카테고리 열인 `category3` 열을 만들어라. `category3` 카테고리는 다음과 같이 정의된다.\n", "\n", "1. 20살 미만이면 성별에 관계없이 \"미성년자\"라고 한다.\n", "2. 20살 이상이면 나이에 따라 \"청년\", \"중년\", \"장년\", \"노년\"을 구분하고 그 뒤에 성별을 나타내는 \"남성\", \"여성\"을 붙인다.\n", "\n", "````" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "celltoolbar": "Edit Metadata", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false } }, "nbformat": 4, "nbformat_minor": 4 }